package com.kasax.skinchange

import android.content.Context
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.ViewCompat

class AttrItem(val attrName: String, val resId: Int)
class AttrView(val view: View, val attrs: MutableList<AttrItem> = mutableListOf()) {
    fun addAttr(attrName: String, resId: Int): AttrView {
        attrs.add(AttrItem(attrName, resId))
        return this
    }
}

open class LayoutInfalatorFactory2(val delegate: AppCompatDelegate) : LayoutInflater.Factory2 {
    private val attrViews: MutableList<AttrView> = mutableListOf()
    override fun onCreateView(parent: View?, name: String, context: Context, attrs: AttributeSet): View? {
        val obtainStyleableAttrs = context.obtainStyledAttributes(attrs, R.styleable.SkinSupport)
        val isEnableSkin = obtainStyleableAttrs.getBoolean(R.styleable.SkinSupport_enableSkin, false)
        obtainStyleableAttrs.recycle()
        var createView: View? = null
        // 如果控件支持换肤
        if (isEnableSkin) {
            // 调用系统方法创建控件
            createView = delegate.createView(parent, name, context, attrs)
            var attrView = AttrView(createView)
            for (i in 0 until attrs.attributeCount) {
                val attrName = attrs.getAttributeName(i)
                // 如果是支持换肤的属性
                if (isSupportAttr(attrName)) {
                    val attrValue = attrs.getAttributeValue(i)
                    if (attrValue.startsWith("?")) {
                        val attrId = attrValue.substring(1)
                        val resIdFromTheme = getResIdFromTheme(context, attrId.toInt())
                        if (resIdFromTheme > 0) {
                            attrView.attrs.add(AttrItem(attrName, resIdFromTheme))
                        }
                    } else if (attrValue.startsWith("@")) {
                        attrView.attrs.add(AttrItem(attrName, attrValue.substring(1).toInt()))
                    }
                }
            }
            attrViews.add(attrView)
        }
        return createView
    }

    override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? {
        return null
    }

    /**
     * 解析主题，找到资源id,其实就是方案一里面的方法
     */
    private fun getResIdFromTheme(context: Context, attrId: Int): Int {
        val typedValue = TypedValue()
        val success = context.theme.resolveAttribute(attrId, typedValue, true)
        // typeValue,resourceId可能为0
        return typedValue.resourceId
    }

    private fun isSupportAttr(attrName: String): Boolean {
        return "textColor" == attrName || "text" == attrName
    }

    fun changeSkin(context: Context) {
        //这个是在Factory2中找到的所有支持换肤的控件
        attrViews.forEach {
            if (ViewCompat.isAttachedToWindow(it.view)) {
                changeAttrView(context, it)
            }
        }
    }

    fun changeAttrView(context: Context, attrView: AttrView) {
        //将每一个换肤控件的属性进行应用
        attrView.attrs.forEach {
            if (attrView.view is TextView) {
                if (it.attrName == "textColor") {
                    //去皮肤包中寻找对应的资源
                    attrView.view.setTextColor(SkingLoader.instance.getTextColor(context, it.resId))
                } else if (it.attrName == "text") {
                    //去皮肤包中寻找对应的资源
                    attrView.view.text = SkingLoader.instance.getText(context, it.resId)
                }
            }
        }
    }

    fun dynamicAddSkin(view: View): AttrView {
        val attrView = AttrView(view)
        attrViews.add(attrView)
        return attrView
    }
}